import {
	ICtrlActionResult,
	IHttpResponse,
	IParam,
	ISearchFormAbility,
	ISearchFormController,
	ISearchFormControllerParams,
	ISearchFormModel,
	ISearchFormStore,
	SearchFormActionType,
} from '@/core/interface';
import { deepCopy } from '@/core/utils';
import { FormController } from './form-controller';

/**
 * 搜索表单控制器
 *
 * @export
 * @class SearchFormController
 * @extends {DECtrlController}
 * @implements {ISearchFormController}
 * @template T
 */
export class SearchFormController
	extends FormController<
		SearchFormActionType,
		ISearchFormStore,
		ISearchFormAbility
	>
	implements ISearchFormController<ISearchFormStore, ISearchFormAbility>
{
	/**
	 * 模型
	 *
	 * @protected
	 * @type {ISearchFormModel}
	 * @memberof SearchFormController
	 */
	protected declare model: ISearchFormModel;

	/**
	 * Creates an instance of SearchFormController.
	 * @param {ISearchFormControllerParams} params
	 * @memberof SearchFormController
	 */
	public constructor(
		params: ISearchFormControllerParams<
			SearchFormActionType,
			ISearchFormAbility
		>
	) {
		super(params);
		this.ctrlInit(params);
	}

	/**
	 * 处理部件初始化
	 *
	 * @protected
	 * @param {ISearchFormControllerParams<SearchFormActionType, ISearchFormAbility>} params
	 * @memberof SearchFormController
	 */
	protected processCtrlInit(
		params: ISearchFormControllerParams<
			SearchFormActionType,
			ISearchFormAbility
		>
	) {
		super.processCtrlInit(params);
		Object.assign(this.store, {
			hasShrinkButton: false,
			shrinkButtonStatus: false,
		});
		this.initShrinkButton();
	}

	/**
	 * 初始化搜索表单大小
	 *
	 * @param {any[]} elList
	 * @param {*} parentEl
	 * @memberof SearchFormController
	 */
	public initShrinkButton() {
		const { detailModel, layoutType } = this.model;
		const maxwidth = layoutType === 'TABLE_24COL' ? 24 : 12;
		let curCol = 0;
		let attr = '';
		const windowWidth = window.innerWidth;
		// 根据当前页面大小
		if (windowWidth < 576) {
			attr = 'colXS';
		} else if (windowWidth < 768 && windowWidth >= 576) {
			attr = 'colSM';
		} else if (windowWidth < 992 && windowWidth >= 768) {
			attr = 'colMD';
		} else if (windowWidth >= 992) {
			attr = 'colLG';
		}
		for (const key in detailModel) {
			const element = detailModel[key];
			curCol +=
				(element?.layout?.[attr] || 0) +
				(element?.layout?.[attr + 'Offset'] || 0);
		}
		if (curCol > maxwidth) {
			this.store.hasShrinkButton = true;
		}
	}

	/**
	 * 收缩按钮点击
	 *
	 * @memberof SearchFormController
	 */
	shrinkButtonClick() {
		this.store.shrinkButtonStatus = !this.store.shrinkButtonStatus;
	}

	/**
	 * 搜索表单值变化
	 *
	 * @param {string} name
	 * @param {*} value
	 * @memberof SearchFormController
	 */
	protected async handleFormValueChange(name: string, value: any) {
		const { enableAutoSearch } = this.model;
		if (
			!name ||
			!this.store.data.hasOwnProperty(name) ||
			Object.is(value, this.store.data[name]) ||
			this.checkIgnoreInput(name, 'before')
		) {
			return;
		}
		this.store.data[name] = value;
		await this.resetFormItem(name);
		this.formDynamicLogic(name);
		await this.formItemUpdate(name);
		if (enableAutoSearch) {
			this.search();
		}
	}

	/**
	 * 加载草稿
	 *
	 * @param {IParam} [opts]
	 * @return {*}  {Promise<ICtrlActionResult>}
	 * @memberof SearchFormController
	 */
	async loadDraft(opts?: IParam): Promise<ICtrlActionResult> {
		const { loadDraftAction } = this.actions;
		if (!loadDraftAction) {
			return { ok: false, data: this.getData(), rowData: { status: 500 } };
		}
		const arg: IParam = { ...opts };
		const { viewParams, context } = this.store;
		Object.assign(arg, { viewParams });
		const tempContext: IParam = deepCopy(context);
		const res = await this.beforeAsyncAction(
			'loadDraft',
			tempContext,
			arg,
			false
		);
		if (!res.ok) {
			return { ok: false, data: this.getData(), rowData: { status: 500 } };
		}
		try {
			const response: IHttpResponse = await this.ctrlService.loadDraft(
				loadDraftAction,
				tempContext,
				{ viewParams: arg }
			);
			const res = await this.afterAsyncAction('loadDraft', response);
			if (!res.ok) {
				return { ok: false, data: this.getData(), rowData: { status: 500 } };
			}
			if (response.success) {
				await this.afterFormAction('loadDraft', response.data);
				this.store.data = response.data;
				this.emit('load', this.getData());
				return { ok: true, data: this.getData(), rowData: response };
			}
			return { ok: false, data: this.getData(), rowData: response };
		} catch (error: any) {
			await this.afterAsyncAction('loadDraft', error);
			return { ok: false, data: this.getData(), rowData: error };
		}
	}

	/**
	 * 表单执行数据行为之后
	 * 1.将行为数据合并到表单数据中
	 * 2.设置表单项启用
	 * 3.表单动态逻辑
	 * 4.表单项更新
	 * 5.转化代码项文本
	 * @protected
	 * @param {string} action
	 * @param {IParam} data
	 * @memberof SearchFormController
	 */
	protected async afterFormAction(action: string, data: IParam) {
		this.store.data = data;
		this.setFormEnableCond();
		this.formDynamicLogic('');
		await this.formItemUpdate('');
		await this.translateCodeListText();
	}

	/**
	 * 搜索
	 *
	 * @protected
	 * @memberof SearchFormController
	 */
	public async search() {
		const tempContext: IParam = deepCopy(this.store.context);
		const res = await this.beforeAsyncAction(
			'search',
			tempContext,
			this.getData(),
			false
		);
		if (!res.ok) {
			return { ok: false, data: this.getData(), rowData: { status: 500 } };
		}
		this.emit('search', this.getData());
	}

	/**
	 * 重置
	 *
	 * @memberof SearchFormController
	 */
	public async reset() {
		const tempContext: IParam = deepCopy(this.store.context);
		const res = await this.beforeAsyncAction(
			'reset',
			tempContext,
			this.getData(),
			false
		);
		if (!res.ok) {
			return { ok: false, data: this.getData(), rowData: { status: 500 } };
		}
		this.loadDraft();
	}

	/**
	 * 获取能力
	 *
	 * @return {*}  {ISearchFormAbility}
	 * @memberof SearchFormController
	 */
	getAbility(): ISearchFormAbility {
		return {
			...super.getAbility(),
		};
	}
}
